package com.zzzy.cont.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhuozhengsoft.pageoffice.word.DataRegionReader;
import com.zzzy.common.util.AssertUtil;
import com.zzzy.common.util.CglibBeanCopierUtil;
import com.zzzy.common.util.FileUtil;
import com.zzzy.common.vo.PageResult;
import com.zzzy.cont.dao.entity.ConFileTemplate;
import com.zzzy.cont.dao.mapper.ConFileTemplateMapper;
import com.zzzy.cont.dto.DataRegionDto;
import com.zzzy.cont.vo.contract.my.ConFileTemplateForSelectPageReq;
import com.zzzy.cont.vo.template.ConFileTemplateAddReq;
import com.zzzy.cont.vo.template.ConFileTemplatePageReq;
import com.zzzy.cont.vo.template.ConFileTemplatePageRes;
import com.zzzy.cont.vo.template.ConFileTemplateSimpleUpdateReq;
import com.zzzy.framework.common.constant.CommonMenuOperateConstant;
import com.zzzy.framework.common.enums.common.TemplateStatusEnum;
import com.zzzy.framework.common.util.SecurityUtils;
import com.zzzy.framework.core.mybatis.query.LambdaQueryWrapperE;
import com.zzzy.framework.dto.LoginUser;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 合同文件模板 服务实现类
 *
 * @author fc
 * @since 2024-05-22
 */
@Service
public class ConFileTemplateService extends ServiceImpl<ConFileTemplateMapper, ConFileTemplate> {

    public PageResult<ConFileTemplate> getConFileTemplatePage(ConFileTemplatePageReq queryReq) {
        LambdaQueryWrapperE<ConFileTemplate> queryWrapperE = new LambdaQueryWrapperE<>();
        queryWrapperE.select(ConFileTemplate::getId, ConFileTemplate::getName, ConFileTemplate::getStatus, ConFileTemplate::getTradeType, ConFileTemplate::getIsFixedFormat
                , ConFileTemplate::getUserId, ConFileTemplate::getUserName, ConFileTemplate::getUpdateTime, ConFileTemplate::getCreateTime);

        queryWrapperE.likeIfPresent(ConFileTemplate::getName, queryReq.getName())
                .likeIfPresent(ConFileTemplate::getUserName, queryReq.getUserName())
                .eqIfPresent(ConFileTemplate::getStatus, queryReq.getStatus())
                .orderByDesc(ConFileTemplate::getId);
        return baseMapper.selectPage(queryReq, queryWrapperE);
    }

    public Long addConFileTemplate(ConFileTemplateAddReq addReq) {
        ConFileTemplate fileTemplate = CglibBeanCopierUtil.copy(addReq, ConFileTemplate.class);
        //初始化word
        byte[] fileByte = FileUtil.getFileByteFromClassPath("office/template/template.docx");
        fileTemplate.setFileBlob(fileByte);
        fileTemplate.setFileExtName("." + FileUtil.DOCX);
        fileTemplate.setStatus(TemplateStatusEnum.CREATE.getValue());
        LoginUser loginUser = SecurityUtils.getLoginUser();
        fileTemplate.setUserId(loginUser.getId());
        fileTemplate.setUserName(loginUser.getNickName());
        fileTemplate.setCreateTime(LocalDateTime.now());
        baseMapper.insert(fileTemplate);
        return fileTemplate.getId();
    }

    public ConFileTemplate getConFileTemplateByIdForQuery(Long id) {
        ConFileTemplate conFileTemplate = baseMapper.selectById(id);
        AssertUtil.nonNull(conFileTemplate, "合同模板不存在");
        return conFileTemplate;
    }

    public ConFileTemplate getConFileTemplateSimpleById(Long id) {
        LambdaQueryWrapperE<ConFileTemplate> queryWrapperE = new LambdaQueryWrapperE<>();
        queryWrapperE.select(ConFileTemplate::getId, ConFileTemplate::getName, ConFileTemplate::getTradeType, ConFileTemplate::getStatus, ConFileTemplate::getUserName
                , ConFileTemplate::getUserId, ConFileTemplate::getCreateTime, ConFileTemplate::getUpdateTime, ConFileTemplate::getIsFixedFormat
                , ConFileTemplate::getDataRegions, ConFileTemplate::getMemo);
        queryWrapperE.eq(ConFileTemplate::getId, id);
        ConFileTemplate conFileTemplate = baseMapper.selectOne(queryWrapperE);
        AssertUtil.nonNull(conFileTemplate, "合同模板不存在");
        return conFileTemplate;
    }

    public void updateBasicInfoById(ConFileTemplateSimpleUpdateReq updateReq) {
        ConFileTemplate conFileTemplate = getConFileTemplateByIdForUpdate(updateReq.getId());
        AssertUtil.isEquals(TemplateStatusEnum.CREATE.getValue(), conFileTemplate.getStatus(), "只有新建状态的模板可修改");
        CglibBeanCopierUtil.copy(updateReq, conFileTemplate);
        conFileTemplate.setUpdateTime(LocalDateTime.now());
        baseMapper.updateById(conFileTemplate);
    }

    private ConFileTemplate getConFileTemplateByIdForUpdate(Long id) {
        ConFileTemplate conFileTemplate = getConFileTemplateByIdForQuery(id);
        Long loginUserId = SecurityUtils.getLoginUser().getId();
        AssertUtil.isEquals(conFileTemplate.getUserId(), loginUserId, "当前用户无修改此模板权限");
        return conFileTemplate;
    }

    public void deleteById(Long id) {
        ConFileTemplate conFileTemplate = getConFileTemplateByIdForUpdate(id);
        AssertUtil.isEquals(TemplateStatusEnum.CREATE.getValue(), conFileTemplate.getStatus(), "只有新建状态的模板可删除");
        baseMapper.deleteById(id);
    }

    public void updateTemplateWord(Long id, byte[] byteArray, String fileExtName) {
        AssertUtil.isTrue(FileUtil.checkIsWord(byteArray), "上传的文件非word格式");
        AssertUtil.isTrue(!FileUtil.isChangeFileExtendType(fileExtName, byteArray), "上传的文件手动修改过文件扩展名,请另存文件后重试");
        ConFileTemplate conFileTemplate = getConFileTemplateByIdForUpdate(id);
        AssertUtil.isEquals(TemplateStatusEnum.CREATE.getValue(), conFileTemplate.getStatus(), "只有新建状态的模板可修改");
        conFileTemplate.setFileBlob(byteArray);
        conFileTemplate.setFileExtName(fileExtName);
        conFileTemplate.setUpdateTime(LocalDateTime.now());
        baseMapper.updateById(conFileTemplate);
    }

    public void updateTemplateDataRegion(Long id, List<DataRegionReader> dataRegionList) {
        ConFileTemplate conFileTemplate = getConFileTemplateByIdForUpdate(id);
        List<DataRegionDto> regionDtoList = dataRegionList.stream()
                .map(dataRegionReader -> new DataRegionDto(dataRegionReader.getName(), dataRegionReader.getValue())).collect(Collectors.toList());
        conFileTemplate.setDataRegions(regionDtoList);
        baseMapper.updateById(conFileTemplate);
    }
    /**
     * 克隆模板
     */
    public Long cloneById(Long id) {
        ConFileTemplate existsConFileTemplate = getConFileTemplateByIdForQuery(id);
        ConFileTemplate fileTemplate = CglibBeanCopierUtil.copy(existsConFileTemplate, ConFileTemplate.class);
        fileTemplate.setId(null);
        fileTemplate.setName(existsConFileTemplate.getName()+"【NEW】");
        fileTemplate.setStatus(TemplateStatusEnum.CREATE.getValue());
        fileTemplate.setCreateTime(LocalDateTime.now());
        baseMapper.insert(fileTemplate);
        return fileTemplate.getId();
    }

    public void enable(Long id) {
        ConFileTemplate conFileTemplate = getConFileTemplateByIdForUpdate(id);
        AssertUtil.isEquals(TemplateStatusEnum.CREATE.getValue(), conFileTemplate.getStatus(), "模板状态错误");
        conFileTemplate.setStatus(TemplateStatusEnum.ENABLE.getValue());
        conFileTemplate.setUpdateTime(LocalDateTime.now());
        baseMapper.updateById(conFileTemplate);
    }

    public void disable(Long id) {
        ConFileTemplate conFileTemplate = getConFileTemplateByIdForUpdate(id);
        AssertUtil.isEquals(TemplateStatusEnum.ENABLE.getValue(), conFileTemplate.getStatus(), "模板状态错误");
        conFileTemplate.setStatus(TemplateStatusEnum.DISABLED.getValue());
        conFileTemplate.setUpdateTime(LocalDateTime.now());
        baseMapper.updateById(conFileTemplate);
    }

    public PageResult<ConFileTemplatePageRes> getConFileTemplateResPage(ConFileTemplatePageReq queryReq) {
        PageResult<ConFileTemplate> conFileTemplatePage = getConFileTemplatePage(queryReq);
        //组装返回数据,判断数据按钮权限
        List<ConFileTemplatePageRes> templatePageResList = conFileTemplatePage.getList().stream().map(docFileTemplate -> {
            ConFileTemplatePageRes.Button button = getButton(docFileTemplate.getId());
            ConFileTemplatePageRes conFileTemplatePageRes = new ConFileTemplatePageRes();
            conFileTemplatePageRes.setData(docFileTemplate);
            conFileTemplatePageRes.setButton(button);
            return conFileTemplatePageRes;
        }).collect(Collectors.toList());

        PageResult pageResult = CglibBeanCopierUtil.copy(conFileTemplatePage, PageResult.class);
        pageResult.setList(templatePageResList);
        return pageResult;
    }

    public ConFileTemplatePageRes.Button getButton(Long docFileTemplateId) {
        ConFileTemplate template = getConFileTemplateByIdForQuery(docFileTemplateId);
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long userId = loginUser.getId();
        boolean hasUpdate = loginUser.hasControllerPermission(CommonMenuOperateConstant.UPDATE);
        ConFileTemplatePageRes.Button button = new ConFileTemplatePageRes.Button();
        boolean isCurrentUser = userId.equals(template.getUserId());
        boolean update = TemplateStatusEnum.CREATE.getValue().equals(template.getStatus())
                && hasUpdate && isCurrentUser;
        button.setUpdate(update);
        button.setDelete(update);
        button.setEnable(update);
        boolean disable = TemplateStatusEnum.ENABLE.getValue().equals(template.getStatus())
                && hasUpdate && isCurrentUser;
        button.setDisable(disable);
        return button;
    }

    public PageResult<ConFileTemplate> getConFileTemplatePageForSelect(ConFileTemplateForSelectPageReq queryReq) {
        LambdaQueryWrapperE<ConFileTemplate> queryWrapperE = new LambdaQueryWrapperE<>();
        queryWrapperE.select(ConFileTemplate::getId, ConFileTemplate::getName, ConFileTemplate::getStatus, ConFileTemplate::getTradeType, ConFileTemplate::getIsFixedFormat
                , ConFileTemplate::getUserId, ConFileTemplate::getUserName, ConFileTemplate::getUpdateTime, ConFileTemplate::getCreateTime);

        queryWrapperE.likeIfPresent(ConFileTemplate::getName, queryReq.getName())
                .eqIfPresent(ConFileTemplate::getStatus, TemplateStatusEnum.ENABLE.getValue())
                .orderByDesc(ConFileTemplate::getId);
        return baseMapper.selectPage(queryReq, queryWrapperE);
    }

}
